package controllers;

import apidocs.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import play.Play;
import play.vfs.VirtualFile;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * API文档
 * Created by zhangzc on 2/17/17.
 */
public class ApiDoc extends BaseCommonController {

    /**
     * 文档首页
     */
    public static void index() {
        VirtualFile docFile = Play.getVirtualFile("apidoc.md");
        if (docFile == null || !docFile.exists()) {
            notFound();
        }
        String text = XJavaExtensionForApi.renderAsTemplate(docFile.contentAsString());
        render(text);
    }

    public static void viewDoc(String fileName) {
        VirtualFile docFile = Play.getVirtualFile("apidoc/" + fileName + ".md");
        if (docFile == null || !docFile.exists()) {
            notFound();
        }

        String text = XJavaExtensionForApi.renderAsTemplate(docFile.contentAsString());
        String title = XJavaExtensionForApi.loadTitle(docFile);
        render(title, fileName, docFile, text);
    }

    /**
     * 浏览API
     *
     * @param className
     * @param methodName
     */
    public static void viewApi(String className, String methodName) {
        Class clazz = Play.classloader.loadApplicationClass(className);
        if (!clazz.isAnnotationPresent(ApiService.class)) {
            forbidden("Must annotate @ApiService");
        }
        Method[] methods = clazz.getMethods();
        Method method = null;
        for (Method m : methods) {
            if (StringUtils.equals(m.getName(), methodName) && m.isAnnotationPresent(Api.class)) { //仅呈现标记了@Api的Action
                method = m;
                break;
            }
        }
        if (method == null) {
            forbidden("Method not found");
        }
        boolean isDuppApi = StringUtils.equalsIgnoreCase(Play.configuration.getProperty("apidoc.dupp", "disable"), "enable");

        if (session.contains(SessionKey_login)) {
            isDuppApi = StringUtils.equalsIgnoreCase(Play.configuration.getProperty("apidoc.user." + session.get(SessionKey_login) + ".dupp", "enable"), (isDuppApi ? "enable" : "disable"));
        }
        render(clazz, method, isDuppApi);
    }

    /**
     * 浏览API
     *
     * @param className
     */
    public static void viewClass(String className) {
        Class clazz = Play.classloader.loadApplicationClass(className);
//        if(!clazz.isAnnotationPresent(ApiResult.class)){
//            forbidden("Must annotate @ApiResult");
//        }
        render(clazz);
    }

    /**
     * 浏览JSON文件里面的API
     *
     * @param className
     * @param methodName
     */
    public static void viewJsonApi(String className, String methodName) {
        JSONObject json = ApiUtils.getApiJson();

        JSONArray arr = json.getJSONArray("api_services");

        JSONObject serviceJson = null;
        JSONObject apiJson = null;

        for (Object _service : arr) {
            JSONObject serviceIt = (JSONObject) _service;
            if (StringUtils.equals(className, serviceIt.getString("name"))) {
                serviceJson = serviceIt;
                for (Object _api : serviceIt.getJSONArray("apis")) {
                    JSONObject apiIt = (JSONObject) _api;
                    if (StringUtils.equals(methodName, apiIt.getString("name"))) {
                        apiJson = apiIt;
                        break;
                    }
                }
                break;
            }
        }

        if (serviceJson == null) {
            forbidden("Service not found");
        }

        if (apiJson == null) {
            forbidden("API not found");
        }
        render(serviceJson, apiJson);
    }

    public static void viewJsonBean(String className) {
        JSONObject json = ApiUtils.getApiJson();
        JSONObject beans = json.getJSONObject("beans");
        JSONObject clazz = beans.getJSONObject(className);
        if (clazz == null) {
            forbidden("Bean not found");
        }
        render(clazz);
    }

    public static void search(String q) {
        final int Max = 10;
        List<SearchResult> results = new ArrayList(Max);
        q = StringUtils.trim(q);
        if (StringUtils.isNotEmpty(q)) {
            SearchEngine.search(results, Max, q);
            if (results.size() > Max) {
                results = results.subList(0, Max);
            }
        }

        renderJSON(results);
    }

    public static void executeDupp(String dupp_url) {
        //屏蔽

    }

    public static void apiStats(String invoker) {
        ApiStatsBean bean = new ApiStatsBean();
        ApiStatsMonitor.Monitor monitor = ApiStatsMonitor.getMonitor();
        if (monitor != null) {
            bean = monitor.getStats(invoker);
        }

        if (bean == null) {
            bean = new ApiStatsBean();
        }
        renderJSON(bean);
    }
}
